package uk.ac.lkl.lpp.ui.xml;



import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import java.awt.GridLayout;
//import java.awt.BorderLayout;

import javax.swing.JComponent;
//import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import uk.ac.lkl.lpp.PedagogyPlan;

import uk.ac.lkl.lpp.ui.BackCompat;
import uk.ac.lkl.lpp.ui.PedagogyPlanUI;
//import uk.ac.lkl.lpp.ui.Messages;
import uk.ac.lkl.lpp.ui.xml.UIElementProcessor;
import uk.ac.lkl.lpp.xml.XMLConstructor;
import uk.ac.lkl.lpp.xml.XMLException;




public class LayoutProcessor extends UIElementProcessor {

    public LayoutProcessor() {
        super("Layout");
    }


    public void convertDataToElements(PedagogyPlanUI ui, Document document,
            Element pedagogyPlanElement) {
        Element element = document.createElement("Layout");
        pedagogyPlanElement.appendChild(element);

        // get ui tabs
        // iterate through classes, creating appropriate XML representation
    }


    public void convertElementToData(PedagogyPlanUI ui, Element element)
            throws XMLException {
        NodeList tabElements = element.getElementsByTagName("Tab");
        int numTabs = tabElements.getLength();
        for (int i = 0; i < numTabs; i++) {
            Node tabElement = tabElements.item(i);
            processTab(ui, (Element) tabElement);
        }
    }


    /**
     * For now, always arranges tab components in vertical gridlayout.
     * 
     * @param ui
     * @param tabElement
     * 
     */
    private void processTab(PedagogyPlanUI ui, Element tabElement)
            throws XMLException {
        String tabName = tabElement.getAttribute("title");
        

        NodeList tabComponentElements = tabElement
                .getElementsByTagName("TabComponent");
        int numTabComponentElements = tabComponentElements.getLength();

        JPanel tab = new JPanel(new GridLayout(numTabComponentElements, 1));
        
        for (int i = 0; i < numTabComponentElements; i++) {
            Element tabComponentElement = (Element) tabComponentElements
                    .item(i);
            JComponent tabComponent = buildTabComponent(ui, tabComponentElement);
            tab.add(tabComponent);
        }

        ui.addTab(tabName, new JScrollPane(tab));
    }


    private JComponent buildTabComponent(PedagogyPlanUI ui,
            Element tabComponentElement) throws XMLException {
    	String className = null;
    	JComponent component = null;
    	
        try {
            className = tabComponentElement.getAttribute("class");
            
            // hack to convert pre 0.72 data files
            if (BackCompat.isOldForm(className)) className = BackCompat.upgrade(className);
            // typically uk.ac.lpp.ui.<X>Panel
            
            Class<?> cl = Class.forName(className);

            try {
            	Constructor<?> constructor = cl
                        .getConstructor(PedagogyPlan.class);
                component = (JComponent) constructor.newInstance(ui.getPlan());
            }
            catch (NoSuchMethodException e) {
                String xmlConstructorClassName = className + "XMLConstructor";
                Class<?> handlerClass = Class.forName(xmlConstructorClassName);

                XMLConstructor xmlConstructor = (XMLConstructor) handlerClass
                        .newInstance();
                Object object = xmlConstructor.createFromXML(ui.getPlan(),
                        tabComponentElement);
                // repeated code
                component = (JComponent) object;
            }

        }
        catch (InstantiationException e) {
            throw new XMLException(e);
        }
        catch (InvocationTargetException e) {
            throw new XMLException(e.getTargetException());
        }
        catch (IllegalAccessException e) {
            throw new XMLException(e);
        }
        catch (ClassCastException e) {
            throw new XMLException(e);
        }
        catch (ClassNotFoundException e) {
            throw new XMLException(e);
        }
        
        return component;

    }
}
